package cn.elead.chaos.sso.core.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;

import cn.elead.chaos.sso.core.constant.SsoConstant;
import cn.elead.chaos.sso.core.util.CookieUtil;
import cn.elead.chaos.sso.core.util.Response;

/**
 * 客户端过滤器
 * 
 * @author luopeng
 *
 */
public class SsoFilter extends SsoInitFilter {

	/**
	 * code的回调
	 * 
	 * @param request
	 * @param response
	 * @param chain
	 * @param servletPath
	 * @throws IOException
	 */
	protected boolean codeCallbackHandler(HttpServletRequest request, HttpServletResponse response, FilterChain chain, String servletPath) throws IOException {
		boolean isNotDoFilter = false;
		if (codeCallback != null && codeCallback.trim().length() > 0 && codeCallback.equals(servletPath)) {
			// 获取token
			Response<String> resToken = getToken(request, response, true);
			if (isnull(resToken)) {
				println(request, response, 400, "{\"code\": 400, \"msg\":\"code不能为空\"}");
				return !isNotDoFilter;
			}
			int status = resToken.getCode();
			if (status == 200) {
				println(request, response, status, JSON.toJSONString(resToken));
			} else {
				println(request, response, status, resToken.getData());
			}
			return !isNotDoFilter;
		}
		return isNotDoFilter;
	}

	/**
	 * 获取用户
	 * 
	 * @param req
	 * @param res
	 * @param chain
	 * @param servletPath
	 * @return
	 * @throws IOException
	 */
	protected boolean getUserHandler(HttpServletRequest request, HttpServletResponse response, FilterChain chain, String servletPath) throws IOException {
		if (ssoUserPath != null && ssoUserPath.trim().length() > 0 && ssoUserPath.equals(servletPath)) {
			// 获取token
			Response<String> resToken = getTokenByHeaders(request, response);
			if (isnull(resToken)) {
				println(response, 400, "{\"code\": 400, \"msg\":\"token不能为空\"}");
				return true;
			}
			int status = resToken.getCode();
			if (status == 200) {
				// 获取用户
				Response<String> remoteData = remoteConnect("/redis/user/" + resToken.getData(), "GET");
				if (remoteData.getCode() == 200) {
					println(response, 200, "{\"code\": 200, \"data\":" + remoteData.getData() + "}");
					return true;
				} else if (remoteData.getCode() == 401) {
					println(response, 401, remoteData.getData());
					return true;
				} else {
					// json msg
					println(response, remoteData.getCode(), remoteData.getData());
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 获取token
	 * 
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@Override
	protected Response<String> getToken(HttpServletRequest request, HttpServletResponse response, boolean isRemote) throws IOException {
		Response<String> resp = null;
		// header指定token模式
		String token = request.getHeader(SsoConstant.PARAM_RESPONSE_TYPE);
		if ("token".equals(token) || "token".equals(token)) {
			return getTokenByHeaders( request,  response);
		}
		// 单点登录模式
		if (("code".equals(responseType) || "CODE".equals(responseType)) && isRemote) {
			// 先看路径参数中是否有code
			String code = request.getParameter(SsoConstant.SSO_CODE);
			if (!isEmpty(code)) {
				// 通过code换取token
				Response<String> remoteData = remoteConnect("/redis/token/" + code, "GET");
				if (remoteData.getCode() == 200) {
					resp = remoteData;
				} else if (remoteData.getCode() == 401) {
					resp = remoteData;
				}
			}
		} else if ("token".equals(responseType) || "TOKEN".equals(responseType)) {
			// 从地址栏参数获取token
			token = request.getHeader(SsoConstant.SSO_TOKEN);
			if (isEmpty(token)) {
				return resp;
			}
			resp = new Response<String>();
			resp.setCode(200);
			// 先看路径参数中是否有code
			resp.setData(token);
		}else {
			// 从Header获取
			resp = getTokenByHeaders(request, response);
		}
		// 最后从cookie
		if (isnull(resp)) {
			//
			String value = CookieUtil.getValue(request, SsoConstant.COOKIE_SESSIONID);
			if (isEmpty(value)) {
				value = request.getHeader(SsoConstant.PARAM_RESPONSE_TYPE);
				if (!"token".equals(value)) {
					return resp;
				}
				value = request.getHeader(SsoConstant.COOKIE_SESSIONID);
			}
			resp = new Response<String>();
			resp.setCode(200);
			// session是否存在
			resp.setData(value);
		}
		return resp;
	}

	/**
	 * 获取token
	 * 
	 * @param request
	 * @return
	 * @throws IOException
	 */
	protected Response<String> getTokenByHeaders(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Response<String> resp = null;
		String token = request.getHeader(xAuthToken);
		if (isEmpty(token)) {
			// token = CookieUtil.getValue(request, SsoConstant.COOKIE_SESSIONID);
			return resp;
		}
		resp = new Response<String>();
		resp.setCode(200);
		resp.setData(token);
		return resp;
	}
}
